/**
 * 
 */
package com.zznode.client.wlanpolling.test;

import java.util.HashMap;
import java.util.Map;
import java.util.Random;
import java.util.Timer;
import java.util.TimerTask;

import org.achartengine.GraphicalView;
import org.achartengine.chart.BarChart;
import org.achartengine.chart.XYChart;
import org.achartengine.model.XYMultipleSeriesDataset;
import org.achartengine.model.XYSeries;
import org.achartengine.renderer.XYMultipleSeriesRenderer;
import org.achartengine.renderer.XYSeriesRenderer;

import android.app.Activity;
import android.content.Context;
import android.graphics.Color;
import android.graphics.Paint.Align;
import android.net.wifi.WifiInfo;
import android.net.wifi.WifiManager;
import android.os.AsyncTask;
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.LinearLayout;
import android.widget.LinearLayout.LayoutParams;
import android.widget.ScrollView;
import android.widget.TextView;
import android.widget.Toast;

import com.zznode.client.wlanpolling.R;
import com.zznode.client.wlanpolling.WLANPollingApplication;
import com.zznode.client.wlanpolling.model.TestResultConstants;
import com.zznode.client.wlanpolling.model.WLANPollManager;
import com.zznode.client.wlanpolling.service.NetworkProber;
import com.zznode.client.wlanpolling.utils.AbstractMessageUpdater;
import com.zznode.client.wlanpolling.utils.IMessageUpdater;
import com.zznode.client.wlanpolling.utils.NetworkUtils;
import com.zznode.client.wlanpolling.utils.PingTask;
import com.zznode.client.wlanpolling.utils.PingUtils;

/**
 * @author Jerome
 *
 */
public class APSwitchTestActivity extends Activity {

	private GraphicalView chart = null;
	private XYMultipleSeriesDataset dataset = new XYMultipleSeriesDataset();
	private XYMultipleSeriesRenderer renderer = new XYMultipleSeriesRenderer();
	
	private double MAX = 100;
	private int number = 60;
	private int count = 0;
	
	private Handler handler = null;
	private WifiManager mgr = null;
//	private BroadcastReceiver receiverWifi;
	private String crtSSID = null;
	private String ap1_ssid = null;
	private String ap2_ssid = null;
	private XYSeries crtSeries = null;
	
	private TextView tv_ping = null;
	private TextView tv_lost = null;
	private TextView tv_delay = null;
	private TextView tv_pkglost = null;
	private TextView tv_mindelay = null;
	private TextView tv_maxdelay = null;
	
	protected Button btn_starttest = null;
	protected Button btn_stoptest = null;	
	
	private AsyncTask<String, String, String> autoPingTask = null;
	
	private Timer timer = null;
	private WLANPollingApplication application;
	
	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.apswitch);
		application = (WLANPollingApplication)getApplication();
		populateUI();
		
		//更新ChartView
		handler = new Handler(){

			@Override
			public void handleMessage(Message msg) {
				if(msg.what == 1){
					chart.invalidate();
				} else if(msg.what == 2) {
					int[] arg = (int[])msg.obj;
					if(arg.length != 2)
						return;
					crtSeries.add(arg[0], arg[1]);
					chart.invalidate();
				}
			}
		};
		
		mgr = (WifiManager) this.getSystemService(Context.WIFI_SERVICE);
		ap1_ssid = crtSSID = mgr.getConnectionInfo().getBSSID();
	}
	
	protected void populateUI(){
		btn_starttest = (Button)this.findViewById(R.id.apswitch_btn);
		btn_starttest.setText("测试");
		btn_starttest.setOnClickListener(new OnClickListener(){

			@Override
			public void onClick(View v) {
				startTestAPSwitch();
			}
			
		});
		initChart();
		btn_stoptest = (Button)this.findViewById(R.id.apswitch_stoptest);
		btn_stoptest.setOnClickListener(new OnClickListener(){

			@Override
			public void onClick(View v) {
				stopTest();
			}
			
		});
		btn_stoptest.setEnabled(false);
//		tv_ping = (TextView)this.findViewById(R.id.apswitch_autoping);
		tv_delay = (TextView)this.findViewById(R.id.apswitch_delay);
		tv_lost = (TextView)this.findViewById(R.id.apswitch_lost);
		tv_pkglost = (TextView)this.findViewById(R.id.apswitch_pkglost);
		tv_mindelay = (TextView)this.findViewById(R.id.apswitch_mindelay);
		tv_maxdelay = (TextView)this.findViewById(R.id.apswitch_maxdelay);
		
		Button btn = (Button)this.findViewById(R.id.apswitch_save);
		btn.setOnClickListener(new OnClickListener(){

			@Override
			public void onClick(View v) {
				saveAction();
			}
			
		});
	}
	
	private String replaceStr(String str1, String str2) {
		return str1.replace(str2, "");
	}
	
	protected void saveAction(){
		String apMac = PingUtils.clearMacAdress(application.getContext().getCurrentWifi().getBSSID());

		Map<String, Object> values = new HashMap<String, Object>();
		
		values.put(TestResultConstants.DEVAP1, ap1_ssid);
		values.put(TestResultConstants.DEVAP2, ap2_ssid);
		values.put(TestResultConstants.CHANGETIMELAG, replaceStr(tv_delay.getText().toString(), "ms"));
		values.put(TestResultConstants.CHANGELOSS, tv_lost.getText().toString());
		values.put(TestResultConstants.SSID, application.getContext().getCurrentWifi().getSSID());
		WLANPollManager.getWLANPollManager().updateTestResult(application.getApplicationContext(), 
				apMac,
				values);
		
		Toast.makeText(this, "成功保存", Toast.LENGTH_SHORT).show();
	}
	
	protected void stopTest(){
		btn_stoptest.setEnabled(false);
		btn_starttest.setEnabled(true);
		clearThreads();
		updateChart();
	}
	
	protected void initChart(){
		renderer.setShowLegend(true);
		renderer.setMarginsColor(Color.DKGRAY);
		renderer.setMargins(new int[]{15, 25, 0, 15});
//		renderer.setFitLegend(true);
		renderer.setShowLabels(true);
//		renderer.setShowGrid(true);
//		renderer.setGridColor(Color.CYAN);
		renderer.setLegendTextSize(15);
		renderer.setXLabels(0);
	    renderer.setYLabels(2);
	    renderer.setXTitle("时间");
	    renderer.setYTitle("场强(dBm)");
	    renderer.setXLabelsAlign(Align.RIGHT);
	    renderer.setYLabelsAlign(Align.RIGHT);
	    renderer.setBarSpacing(0.5);
	    renderer.setXAxisMin(0.5);
	    renderer.setXAxisMax(number * 2 + 0.5);
	    renderer.setYAxisMin(0);
	    renderer.setYAxisMax(MAX);
	    renderer.setLabelsColor(Color.WHITE);
//	    renderer.addXTextLabel(number / 2, "AP1");
//	    renderer.addXTextLabel(number + number / 2, "AP2");
	    renderer.addYTextLabel(50, "50");
	    renderer.addYTextLabel(100, "100");
	    renderer.setPanEnabled(true, false);
	    renderer.setZoomEnabled(false);
	    renderer.setInScroll(true);
	    XYSeriesRenderer rendererAP1 = new XYSeriesRenderer();
	    rendererAP1.setLineWidth(2);
	    rendererAP1.setColor(Color.GREEN);
	    renderer.addSeriesRenderer(rendererAP1);
	    XYSeriesRenderer rendererAP2 = new XYSeriesRenderer();
	    rendererAP2.setLineWidth(2);
	    rendererAP2.setColor(Color.YELLOW);
	    renderer.addSeriesRenderer(rendererAP2);
	    
	    populateDataset();
	    LinearLayout root = (LinearLayout)this.findViewById(R.id.apswitch_placeholder);
	    
	    XYChart xyChart = new BarChart(dataset, renderer, BarChart.Type.DEFAULT);
//	    chart = (GraphicalView)this.findViewById(R.id.apswitch_bar);
	    chart = new GraphicalView(this, xyChart);
//	    chart.initChart(xyChart);
	    LayoutParams params = new LayoutParams(LayoutParams.MATCH_PARENT, 300);
	    root.addView(chart, params);
	    
	    ScrollView sv = new ScrollView(this);	    
	    tv_ping = new TextView(this);
	    params = new LayoutParams(LayoutParams.MATCH_PARENT, LayoutParams.MATCH_PARENT);
	    sv.setBackgroundResource(R.drawable.pingcmd_border);
	    sv.addView(tv_ping, params);	    
	    params = new LayoutParams(LayoutParams.MATCH_PARENT, 200);
	    root.addView(sv, params);
	}
	
	private void startTestAPSwitch(){
		btn_starttest.setEnabled(false);
		btn_stoptest.setEnabled(true);
		initialize();
		final Random random = new Random(100);
		timer = new Timer();
		
		TimerTask task = new TimerTask() {
			public void run() {
				count++;
				if(count > number){
					timer.cancel();
					return;
				}
				
//				mgr.startScan();
				WifiInfo info = mgr.getConnectionInfo();
				if (info != null && crtSSID != null) {
					String _id = info.getBSSID();
					int y = info.getRssi() + 100;
					if (!crtSSID.equals(_id)) {
						// switched to another AP
						XYSeries seriesAP2 = dataset.getSeriesAt(1);
						ap2_ssid = crtSSID = _id;
						crtSeries = seriesAP2;
					}
					//添加坐标数据
					//crtSeries.add(count, y);
					Message msg = new Message();
					msg.what = 2;
					msg.obj = new int[]{count, y};
					handler.sendMessage(msg);
				} else {
					// only for test, need remove this block before distributing
					double y = random.nextInt() % 100;
					while(y < 0){
						y = random.nextInt() % 100;
					}
					
					if(count ==number){
						XYSeries seriesAP2 = dataset.getSeriesAt(1);
						crtSeries = seriesAP2;
					}
					
					Message msg = new Message();
					msg.what = 2;
					msg.obj = new int[]{count, (int)y};
					handler.sendMessage(msg);
				}
			}
		};
		
		timer.schedule(task, 0, 1000); // one check per second
		IMessageUpdater i1 = new AbstractMessageUpdater(this){

			@Override
			public void messageUpdated(String message) {
				tv_ping.append("\n" + message);
			}
			
		};
		IMessageUpdater i2 = new AbstractMessageUpdater(this){

			@Override
			public void messageUpdated(String message) {
				tv_delay.setText(message + "ms");
			}
			
		};
		IMessageUpdater i3 = new AbstractMessageUpdater(this){

			@Override
			public void messageUpdated(String message) {
				tv_lost.setText(message + "%");
			}
			
		};
		IMessageUpdater i4 = new AbstractMessageUpdater(this){

			@Override
			public void messageUpdated(String message) {
				tv_pkglost.setText(message);
			}
			
		};
		IMessageUpdater i5 = new AbstractMessageUpdater(this){

			@Override
			public void messageUpdated(String message) {
				tv_mindelay.setText(message + "ms");
			}
			
		};
		IMessageUpdater i6 = new AbstractMessageUpdater(this){

			@Override
			public void messageUpdated(String message) {
				tv_maxdelay.setText(message + "ms");
				btn_starttest.setEnabled(true);
			}
			
		};
		
		String gateway = null;
		try {
			gateway = NetworkUtils.intToIp(new NetworkProber(this).getDhcpInfo().gateway);
		} catch (Exception e) {
			gateway = "127.0.0.1";
		}
		
		//
		String pingParams = application.getContext().getSystemSetting().getApPingParams();
		if(pingParams == null || pingParams == "") {
			pingParams = " -c 300 -s 64 ";
		}
		autoPingTask = new PingTask(new IMessageUpdater[]{i1, i2, i3, i4, i5, i6}, null).execute(new String[]{pingParams, gateway});
	}
	
	
	
	private void populateDataset(){		
		XYSeries seriesAP1 = new XYSeries("AP1");
//		seriesAP1.add(count, 0);
	    dataset.addSeries(seriesAP1);
	    XYSeries seriesAP2 = new XYSeries("AP2");
//		seriesAP2.add(count, 0);
		dataset.addSeries(seriesAP2);
	    crtSeries = seriesAP1;
	}
	
	private void initialize(){
		clearThreads();
		count = 0;
		int size = dataset.getSeriesCount();
		for(int i = 0; i < size; i++){
			dataset.removeSeries(0);
		}
		populateDataset();
		if(tv_ping != null){
			tv_ping.setText("");
		}
	}
	
	protected void updateChart(){
		Message message = new Message();
		message.what = 1;
		handler.sendMessage(message);
	}
	
	@Override
	public void onBackPressed() {
//		unregisterReceiver(receiverWifi);
		clearThreads();
		super.onBackPressed();
	}
	
	protected void clearThreads(){
		if(timer != null){
			timer.cancel();
			timer.purge();
		}
		if(autoPingTask != null && !autoPingTask.isCancelled()){
			autoPingTask.cancel(true);
		}
	}
}
